package metricsdata;

/**
 * The abstract super class for all Metrics.
 * Metrics can be of various type, e.g.
 * - A single floating point number (@DoubleValueMetric)
 * - A list of floating point numbers (@DoubleArrayValueMetric)
 * - A list of lists of floating point numbers (@DoubleArray2ValueMetric)
 * - An item from a set, e.g. TRUE from {TRUE,FALSE} (not implemented yet)
 * - more complicated structures like trees are thinkable 
 * 
 * This abstract class contains all common attributes 
 * and implements following functions (that all metrics have in common):
 * - check if metric was changed (e.g. for DB cache)
 * - get value as Object
 * 
 */
public abstract class AbstractMetricAttribute{
	
	
	/** the description for that metric*/
	private String description = "No long description available";
	
	/** the full name of the metric, e.g. Lines of Code*/ 
	private String fullName = "No full name available";
	
	/** 
	 * the shortcut for that metric, e.g. LOC - must be set!
	 */
	protected String shortcut;
	
	
	
	/**
	 * Constructor called by children.
	 * @param value
	 * @param idOfMetricNamesInterface
	 */
	public AbstractMetricAttribute(String shortcut, String fullName, String description){
		
		//initialize metric's info attributes with the information stored in metricNames
		this.shortcut = shortcut;
		this.fullName = fullName;
		this.description = description;
		
	}
	
	

	//Methods that have to be overwritten by subclasses
	
	public abstract Object getValue();
	
	/**
	 * Returns a String representation of the value stored.
	 */
	public abstract String toDatabaseString();
	
	/**
	 * Returns the max value for that metric.
	 * This is useful when metric results contain multiple measurements.
	 * @return the max value, or null if the metric is null or the the content is null.
	 */
	public abstract Object getMaxValue();
	
	/**
	 * Returns the min value for that metric.
	 * This is useful when metric results contain multiple measurements.
	 * @return the min value, or null if the metric is null or the the content is null.
	 */
	public abstract Object getMinValue();
	
	/**
	 * Returns the first value for that metric.
	 * In case the metric does only contain one value (e.g. one Double) the value is given back.
	 * If the metric is a collection of measurement results then the first is given back.
	 * @return the first value, or if the metric is null or the first element is null.
	 */
	public abstract Object getFirstValue();
	
	/**
	 * Returns the sum over all stored values.
	 * This is useful when metric results contain multiple measurements.
	 * @return the sum, or null if metric is null or all elements are null
	 */
	public abstract Object getSumValue();
	
	/**
	 * Returns the average over all stored values.
	 * This is useful when metric results contain multiple measurements.
	 * @return the average, or null if metric is null or all elements are null
	 */
	public abstract Object getAvgValue();
	
	/**
	 * Returns the number of items stored in the metric.
	 * 
	 * @return the item count, or null if metric is null.
	 */
	public abstract Integer getItemCount();
	
	/**
	 * Overwrites Object.equals().
	 * Needed to compare if two metrics hold the same value.
	 * @return
	 */
	public boolean equals(AbstractMetricAttribute ama){
		return (ama.shortcut.equals(this.shortcut) 
				&& ama.getValue().equals(this.getValue()));
	}
	
	
	//*****************************//
	//      GETTER AND SETTER      //
	//*****************************//
	
	
	public String getDescription(){
		return description;
	}
	
	public String getShortcut() {
		return shortcut;
	}
	
	public String getFullName() {
		return fullName;
	}
	
	
	public String toString() {
		return this.toDatabaseString();
	}
	
	
	
}
